package headfirst.designpatterns.factory.b_pizzafm_factorymothod.z_run_test;

import headfirst.designpatterns.factory.b_pizzafm_factorymothod.pizza.Pizza;
import headfirst.designpatterns.factory.b_pizzafm_factorymothod.pizzastore.ChicagoPizzaStore;
import headfirst.designpatterns.factory.b_pizzafm_factorymothod.pizzastore.NYPizzaStore;
import headfirst.designpatterns.factory.b_pizzafm_factorymothod.pizzastore.PizzaStore;

/**
 * 测试工厂方法
 * 定义：
 * 		定义一个创建对象的接口，但有子类决定要实力化的类是哪一个，工厂方法让类把实力化推迟到子类。
 * 重点：
 * 		子类来决定创建的对象，创建者不需要知道创建了哪种具体的产品
 *
 * 与上一个例子（普通工厂）比就是将创建披萨的方法交给子类（顾客），不再由披萨店直接决定
 * 由于披萨店只有orderPizza的方法，真正createPizza在子类中，披萨店并不知道哪个子店类将实际上制作披萨
 * 由于披萨也是抽象的，order也不知道哪些披萨将被制作出来
 * 所以披萨店就完成了接耦
 *
 * 结果是同一款披萨 不同披萨店可以做出与其他披萨店不同风味的披萨
 * 每一个想要的披萨都是有存在的实体类，想要添加披萨只需要添加实体类加在对应的店内即可，完全不影响其他店铺
 */
public class PizzaTestDrive {
 
	public static void main(String[] args) {
		// 纽约风味商店
		PizzaStore nyStore = new NYPizzaStore();
		// 芝加哥风味商店
		PizzaStore chicagoStore = new ChicagoPizzaStore();

		// 纽约 芝士披萨
		Pizza pizza = nyStore.orderPizza("cheese");
		System.out.println("Ethan 点了一个 " + pizza.getName() + "\n");
		// 芝加哥 芝士披萨
		pizza = chicagoStore.orderPizza("cheese");
		System.out.println("Joel 点了一个 " + pizza.getName() + "\n");

		// 纽约 蛤蜊披萨
		pizza = nyStore.orderPizza("clam");
		System.out.println("Ethan 点了一个 " + pizza.getName() + "\n");
		// 芝加哥 蛤蜊披萨
		pizza = chicagoStore.orderPizza("clam");
		System.out.println("Joel 点了一个 " + pizza.getName() + "\n");

		// 纽约 意大利辣香肠披萨
		pizza = nyStore.orderPizza("pepperoni");
		System.out.println("Ethan 点了一个 " + pizza.getName() + "\n");
		// 芝加哥 意大利辣香肠披萨
		pizza = chicagoStore.orderPizza("pepperoni");
		System.out.println("Joel 点了一个 " + pizza.getName() + "\n");

		// 纽约 素食披萨
		pizza = nyStore.orderPizza("veggie");
		System.out.println("Ethan 点了一个 " + pizza.getName() + "\n");
		// 芝加哥 素食披萨
		pizza = chicagoStore.orderPizza("veggie");
		System.out.println("Joel 点了一个 " + pizza.getName() + "\n");
	}
}
